package web.controller.sys;

import com.github.pagehelper.PageInfo;
import framework.base.provider.DynamicUpdateProvider;
import framework.config.UserConfig;
import framework.crypto.GeneralCrypto;
import framework.defined.SystemDefined;
import framework.proxy.DynamicEntityProxy;
import framework.security.AuthService;
import framework.security.RegApproval;
import framework.utils.MapperUtil;
import framework.utils.RequestUtil;
import framework.vo.R;
import framework.vo.ResultInfo;
import framework.vo.ResultList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import system.dto.UserSenseQuery;
import system.dto.sys.SysUserQuery;
import system.dto.sys.SysUserUpdate;
import system.entity.SysRoleUser;
import system.entity.SysUser;
import system.service.sys.SysRoleUserService;
import system.service.sys.SysUserService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/sys/user")
@Api(tags = "用户管理")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private AuthService authService;
    @Autowired
    private UserConfig userConfig;
    @Autowired
    private SysRoleUserService sysRoleUserService;
    @Autowired
    private GeneralCrypto generalCrypto;

    @ApiOperation("添加账号")
    @PostMapping("/add")
    public ResultInfo<Integer> add(@ModelAttribute SysUser param) {
        Date now = new Date();
        param.setCreateTime(now);
        param.setUpdateTime(now);
        param.setId(null);
        //
        if (this.generalCrypto.enable()) {
            String password = param.getPassword();
            if (StringUtils.hasText(password)) {
                password = this.generalCrypto.decryptFromBase64AsString(password);
                param.setPassword(password);
            }
        }
        //
        Integer added = sysUserService.add(param);
        ResultInfo<Integer> info = new ResultInfo<>(added);
        return info;
    }

    @ApiOperation("删除账号")
    @PostMapping("/del")
    public ResultInfo<Integer> del(@RequestParam("ids") Long[] ids) {
        long accountId = this.authService.getAccountId();
        int deleted = 0;
        for (Long id : ids) {
            if (this.userConfig.checkIsSuperAdminId(id)) {
                return R.failed(RequestUtil.getMessageDefault("sys.object.not.allow.deleted", "System object cannot be deleted"));
            }
            if (id == accountId) {
                return R.failed(RequestUtil.getMessageDefault("user.cannot.delete.self", "your cannot delete self"));
            }
            deleted += sysUserService.deleteById(id);
        }
        ResultInfo<Integer> info = new ResultInfo<>(deleted);
        return info;
    }

    @ApiOperation("编辑账号")
    @PostMapping("/edit")
    public ResultInfo<Integer> edit(@ModelAttribute @Validated SysUserUpdate param) {
        SysUser update = MapperUtil.dynamicEntity(SysUser.class);
        BeanUtils.copyProperties(param, update);
        Integer updated = sysUserService.update(update);
        ResultInfo<Integer> info = new ResultInfo<>(updated);
        return info;
    }

    @ApiOperation("密码重置")
    @PostMapping("/password")
    public ResultInfo<Integer> passwordReset(
            @RequestParam Long id
            , @RequestParam String password
            , @RequestParam Integer isNextModify
    ) {
        int updated = 0;
        if (this.generalCrypto.enable()) {
            password = this.generalCrypto.decryptFromBase64AsString(password);
        }
        updated += sysUserService.setPassword(id, password, isNextModify == SystemDefined.YES_VALUE);
        ResultInfo<Integer> info = new ResultInfo<>(updated);
        return info;
    }

    @ApiOperation("启用/禁用")
    @PostMapping("/disable")
    public ResultInfo<Integer> disable(
            @RequestParam Long id
            , @RequestParam Integer value
            , @RequestParam String cause
    ) {
        int updated = 0;
        boolean disabled = value == 1 ? true : false;
        updated += sysUserService.disable(id, disabled, cause);
        ResultInfo<Integer> info = new ResultInfo<>(updated);
        return info;
    }

    @ApiOperation("账号审批")
    @PostMapping("/approve")
    public ResultInfo<Integer> approve(@RequestParam Long[] ids, @RequestParam RegApproval approval, String msg) {
        int updated = 0;
        long accountId = this.authService.getAccountId();
        for (Long id : ids) {
            if (accountId == id) {
                return R.failed(RequestUtil.getMessageDefault("error.target.not.operate", "not allow operate to target object"));
            }
            if (this.userConfig.checkIsSuperAdminId(id)) {
                return R.failed(RequestUtil.getMessageDefault("error.user.not.operate", "this operation is cannot to target user"));
            }
        }
        for (Long id : ids) {
            updated = sysUserService.approve(id, approval, msg);
        }
        ResultInfo<Integer> info = new ResultInfo<>(updated);
        return info;
    }

    @ApiOperation("账号信息")
    @GetMapping("/info")
    public ResultInfo<SysUser> info(@RequestParam("id") Long id) {
        SysUser info = sysUserService.loadById(id);
        return new ResultInfo<>(info);
    }

    @ApiOperation("账号列表")
    @GetMapping("/list")
    public ResultList<SysUser> list(SysUserQuery query,
                                    @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                    @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        PageInfo<SysUser> info = sysUserService.search(query, pageIndex, pageSize);
        return new ResultList<>(info);
    }

    @ApiOperation("账号感知")
    @GetMapping("/sense")
    public ResultList<SysUser> sense(UserSenseQuery senseQuery,
                                     @RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                     @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        if (senseQuery.checkEmpty()) {
            return new ResultList<>(new ArrayList<>());
        }
        PageInfo<SysUser> info = PageInfo.of(sysUserService.sense(senseQuery, pageIndex, pageSize));
        return new ResultList<>(info);
    }

    @ApiOperation("用户角色列表")
    @GetMapping("/roles/list")
    public ResultList<SysRoleUser> rolesList(Long userId) {
        SysRoleUser query = new SysRoleUser();
        query.setUserId(userId);
        List<SysRoleUser> roleUsers = sysRoleUserService.load(query);
        return new ResultList<>(roleUsers);
    }

    @ApiOperation("用户角色设置")
    @PostMapping("/roles/save")
    public ResultInfo<Integer> rolesSave(Long userId, Integer[] roleIds) {
        List<Integer> list = roleIds == null ? new ArrayList<>() : Arrays.asList(roleIds);
        int rows = sysRoleUserService.setUserRoles(userId, list);
        return new ResultInfo<>(rows);
    }

}